package com.redfootdev.horseskills;

import java.util.List;
import java.util.ListIterator;

import org.bukkit.ChatColor;
import org.bukkit.GameMode;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.metadata.FixedMetadataValue;
import org.bukkit.metadata.MetadataValue;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Horse;
import org.bukkit.entity.Player;
import org.bukkit.entity.Vehicle;
import org.bukkit.event.Event;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.HandlerList;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.CreatureSpawnEvent;
import org.bukkit.event.entity.EntityDamageByEntityEvent;
import org.bukkit.event.entity.EntityDamageEvent;
import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
import org.bukkit.event.entity.EntityDeathEvent;
import org.bukkit.event.entity.EntityInteractEvent;
import org.bukkit.event.entity.EntityTameEvent;
import org.bukkit.event.entity.EntityTargetLivingEntityEvent;
import org.bukkit.event.entity.EntityTeleportEvent;
import org.bukkit.event.entity.HorseJumpEvent;
import org.bukkit.event.entity.PlayerDeathEvent;
import org.bukkit.event.inventory.InventoryInteractEvent;
import org.bukkit.event.player.PlayerInteractEntityEvent;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerLoginEvent;
import org.bukkit.event.player.PlayerMoveEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.event.player.PlayerTeleportEvent;
import org.bukkit.event.vehicle.VehicleBlockCollisionEvent;
import org.bukkit.event.vehicle.VehicleCollisionEvent;
import org.bukkit.event.vehicle.VehicleCreateEvent;
import org.bukkit.event.vehicle.VehicleDamageEvent;
import org.bukkit.event.vehicle.VehicleDestroyEvent;
import org.bukkit.event.vehicle.VehicleEnterEvent;
import org.bukkit.event.vehicle.VehicleEntityCollisionEvent;
import org.bukkit.event.vehicle.VehicleExitEvent;
import org.bukkit.event.vehicle.VehicleMoveEvent;
import org.bukkit.event.vehicle.VehicleUpdateEvent;
import org.bukkit.scheduler.BukkitTask;
import org.bukkit.util.Vector;
import com.redfootdev.horseskills.Trample;
import com.redfootdev.horseskills.Strength;
import com.redfootdev.horseskills.HorseSkills;
import com.redfootdev.horseskills.HorseDatabase;

import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType;

public class HorseMonitor implements Listener, Runnable {

	private JavaPlugin plugin;

	private int taskNumber;
	private HorseEffects horseEffects;
	private boolean horseDirectionFix;



	// test comment 
	
	public HorseMonitor(JavaPlugin plugin, HorseDatabase hdb, PlayerDatabase pdb) {

		this.plugin = plugin;
		horseEffects = new HorseEffects(plugin, hdb, pdb);
		// load in all the config values and setting them to variables. No error
		// checks done here.
		// Checks were done in onEnable by the CheckConfig() method

		if (true) {
			plugin.getLogger().info("Monitoring horsies.");
		}

		// registers this event and schedules a task for it in the run() method.
		plugin.getServer().getPluginManager().registerEvents(this, plugin);
		// taskNumber =
		// plugin.getServer().getScheduler().scheduleSyncRepeatingTask(plugin,
		// this, 40l, 20l);

	}

	// Checks to see if a player died, if so, it resets their insanity monitor.
	@EventHandler
	public void onVehicleEnter(VehicleEnterEvent v) {
		if (v.getEntered().getType() == EntityType.PLAYER) {
			if (v.getVehicle().getType() == EntityType.HORSE) {
				plugin.getLogger().info("Proccessing horse mount");
				if(!horseEffects.horseMounted(v.getVehicle(), (Player)v.getEntered())) {
					// You were unable to mount the horse.
					v.setCancelled(true);
					((Player) v.getEntered()).sendMessage(ChatColor.RED + "You are carrying to much!");
				}
				//hdb.setAgility(v.getVehicle(), 1);
			}
		}
	}
	
	@EventHandler
	public void onVehicleExit(VehicleExitEvent v) {
		if (v.getExited().getType() == EntityType.PLAYER) {
			if (v.getVehicle().getType() == EntityType.HORSE) {
				horseEffects.horseDismounted(v.getVehicle(), (Player)v.getExited());
			}
		}

	}
	
	@EventHandler
	public void onVehicleMove(VehicleMoveEvent v) {
		Entity rider = v.getVehicle().getPassenger();
		Entity horse = v.getVehicle();
		List<Entity> entityList;
		if(horse.getType() == EntityType.HORSE && rider != null) {
			plugin.getLogger().info("Trampling possible");

			if(rider.getType() == EntityType.PLAYER) {
				
				entityList = horse.getNearbyEntities(0, 0, 0);
				if(entityList.size() > 0) {
					for(Entity victim: entityList) {
						plugin.getLogger().info("Trampling a: " + victim.getType().getName());
						horseEffects.horseHitSomething(horse, (Player)rider, victim);
					}
				}
			}
		}
		
		
	}
	
	@EventHandler
	public void onVehicleEntityCollision(VehicleEntityCollisionEvent v) {

			if (v.getVehicle().getType() == EntityType.PIG) {
				plugin.getLogger().info("horse has collided with an entity.");
			}
	}
	
/*	@EventHandler
	public void onVehicleBlockCollision(VehicleBlockCollisionEvent v) {

			if (v.getVehicle().getType() == EntityType.HORSE) {
				plugin.getLogger().info("horse has collided with block.");
			}
	}
*/	
/*	@EventHandler
	public void onVehicleUpdate(VehicleUpdateEvent v) {
		plugin.getLogger().info("vehicle update.");
			if (v.getVehicle().getType() == EntityType.HORSE) {
				plugin.getLogger().info("horse update.");
			}
	}
*/	
	public void onPlayerInteractEvent() {
		
	}


	@EventHandler
	public void onCreatureSpawn(CreatureSpawnEvent v) {

		if (v.getEntityType() == EntityType.HORSE) {
			plugin.getLogger().info("horse created");
			plugin.getLogger().info("Horse with ID: " + v.getEntity().getUniqueId() + " (" + v.getEntity().getEntityId() + ") " + "has been created");
		}
	}

	@EventHandler
	public void onHorseJump(HorseJumpEvent v) {

		
			plugin.getLogger().info("horse has jumped");
			
			horseEffects.horseJumped(v.getEntity(), (Player)(v.getEntity().getPassenger()), v.getPower());
		
	}

	@EventHandler
	public void onEntityTeleport(EntityTeleportEvent v) {

		if (v.getEntityType() == EntityType.HORSE) {
			plugin.getLogger().info("horse has teleported");
		}
	}

	@EventHandler
	public void onEntityTargetLivingEntity(EntityTargetLivingEntityEvent v) {

		if (v.getTarget().getType() == EntityType.ZOMBIE) {
			plugin.getLogger().info("horse found target");
		}
	}


	@EventHandler
	public void onEntityTame(EntityTameEvent v) {

		if (v.getEntityType() == EntityType.HORSE) {
			plugin.getLogger().info("horse has been tamed");
		}
	}

	@EventHandler
	public void onEntityDeath(EntityDeathEvent v) {

		if (v.getEntityType() == EntityType.HORSE) {
			plugin.getLogger().info("horse has died");
			horseEffects.horseHasDied(v.getEntity());
		}
		
	}


	@EventHandler
	public void onEntityDamageByEntity(EntityDamageByEntityEvent v) {

		Entity rider = v.getEntity().getPassenger();
		Entity horse = v.getEntity();
		if(horse.getType() == EntityType.HORSE && rider != null) {

			if(rider.getType() == EntityType.PLAYER)
			plugin.getLogger().info("horse damaged by entity");
			horseEffects.horseWasHitBySomething(horse, (Player)rider, (int)v.getDamage());
		}
	}
	@EventHandler
	public void onEntityDamage(EntityDamageEvent v) {

			if (v.getEntityType() == EntityType.HORSE){
				if (!((v.getEntity().getPassenger()) == null)){
					if(v.getCause() == DamageCause.FALL) {
						plugin.getLogger().info("horse recieved fall damage");
						horseEffects.horseFell(v.getEntity(), (Player)v.getEntity().getPassenger(), v.getDamage());
					}
				}
			}
		
	}
	//TODO: Fix Change direction on horse interact if bukkit doesn't do it first.
	@EventHandler(priority = EventPriority.HIGHEST)
	public void onPlayerInteractEntity(PlayerInteractEntityEvent v) {
			
			if (v.getRightClicked().getType() == EntityType.HORSE) {
				//Temporary Fix for horse interact problem. Remove if glitch disappears.
				horseDirectionFix = true;
				
				if (horseEffects.horseInteractedWith(v.getRightClicked(), v.getPlayer())) {
					v.setCancelled(true);
					if (horseEffects.isConsumableItem(v.getPlayer().getItemInHand())) {
						v.getPlayer().getItemInHand().setAmount(v.getPlayer().getItemInHand().getAmount()-1);
					}
				}
				plugin.getLogger().info("horse is eating potato!");
			}
		
	}
	@EventHandler
	public void onPlayerInteract(PlayerInteractEvent v) {
		
		plugin.getLogger().info("I got a Richt Click Event");
		if(horseEffects.playerRightClicked(v.getPlayer())) {
			v.setCancelled(true);
		}
	}
	@EventHandler
	public void onPlayerMove(PlayerMoveEvent v) {
		if(v.getTo().getX() == v.getFrom().getX() && v.getTo().getZ() == v.getFrom().getZ()) {
			if(horseDirectionFix){
				v.setCancelled(true);
				horseDirectionFix = false;
			}
			return;
		}
			if (v.getPlayer().getVehicle() != null){
				if (v.getPlayer().getVehicle().getType() == EntityType.HORSE) {
					List<Entity> stuff =  v.getPlayer().getNearbyEntities(1, 1, 1);
					for (Entity target: stuff) {
					horseEffects.horseHitSomething(v.getPlayer().getVehicle(), v.getPlayer(), target);
				}
			}
		}
	}

	@EventHandler
	public void onPlayerLogin(PlayerLoginEvent v) {

			
				plugin.getLogger().info(v.getPlayer().getName() + " has logged in.");
				//TODO: Figure out horseTime
			
	}
	
	@EventHandler
	public void onPlayerTeleport(PlayerTeleportEvent v) {
		List<Entity> stuff =  v.getPlayer().getNearbyEntities(1, 1, 1);
		for (Entity target: stuff) {
			if(target.getType() == EntityType.HORSE){
				horseEffects.playerTeleportedNextToHorse(v.getPlayer(), (Horse)target, v.getTo());
			} 
		}
			
	}
	
	@EventHandler
	public void onPlayerQuit(PlayerQuitEvent v) {

			
				plugin.getLogger().info(v.getPlayer().getName() + " has logged out.");
				//TODO: Figure out horseTime 
			
	}

	public void run() {

	}
	
	
	

}